/*
 * Copyright 2009 BioTeam Inc
 * 
 * Licensed under License GNU LESSER GENERAL PUBLIC LICENSE version 3.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.gnu.org/copyleft/lesser.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package net.bioteam.appweb.gwt.apps.client.user;

import net.bioteam.appweb.gwt.apps.client.StaticHolder;
import net.bioteam.appweb.gwt.apps.client.Util.ApplicationCallBack;
import net.bioteam.appweb.gwt.apps.clientandserver.Constant;
import net.bioteam.appweb.gwt.apps.clientandserver.user.JobRet;
import net.bioteam.appweb.gwt.apps.clientandserver.user.UserAction;
import net.bioteam.appweb.submit.RunStatus;
import net.bioteam.appweb.submit.RunStatusCode;

import com.google.gwt.user.client.History;
import com.smartgwt.client.rpc.RPCResponse;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.DateDisplayFormat;
import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.types.SelectionAppearance;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.grid.CellFormatter;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.CellClickEvent;
import com.smartgwt.client.widgets.grid.events.CellClickHandler;
import com.smartgwt.client.widgets.grid.events.HeaderClickEvent;
import com.smartgwt.client.widgets.grid.events.HeaderClickHandler;
import com.smartgwt.client.widgets.tree.Tree;
import com.smartgwt.client.widgets.tree.TreeNode;

public class JobGrid extends ListGrid
{

	public final static int JobGridWidth=610;
	
	public JobGrid()
	{
		setWidth(JobGridWidth);
		//setHeight100();
		setAlternateRecordStyles(true);
		setShowAllRecords(false);
		setShowEmptyMessage(true);
		setEmptyMessage("No job is available");
		setDateFormatter(DateDisplayFormat.TOUSSHORTDATETIME);
		//setDrawAheadRatio(2.0f);
		//setWrapCells(true);
		// setAutoFitData(Autofit.HORIZONTAL);
		// setCanRemoveRecords(true);

		setSelectionType(SelectionStyle.SIMPLE);  
		setSelectionAppearance(SelectionAppearance.CHECKBOX);  
		//http://code.google.com/p/smartgwt/issues/detail?id=257
		addHeaderClickHandler(new HeaderClickHandler(){

			public void onHeaderClick(HeaderClickEvent event)
			{
				if (event.getFieldNum()!=0)
				{
					return;
				}
				if (getSelection().length!=0)
				{
					deselectAllRecords();
					event.cancel();
					return;
				}
				Integer[] selected=getVisibleRows();
				
				int[] selects=new int[selected[1]-selected[0]+1];
				for (int i=selected[0]; i<=selected[1]; i++)
				{
					selects[i-selected[0]]=i;
				}
				selectRecords(selects, true);
				event.cancel();
			}});
		
		setDataSource(new JobsDataSource());

		ListGridField jobIdField = new ListGridField("id", "Job ID", 60);
		jobIdField.setType(ListGridFieldType.TEXT);
		jobIdField.setBaseStyle("fakelink");
		
		ListGridField clusterField = new ListGridField("clusterid", "Cluster ID", 60);
		clusterField.setType(ListGridFieldType.INTEGER);
		clusterField.setCanSort(false);
		clusterField.setCellFormatter(new CellFormatter(){

			public String format(Object value, ListGridRecord record, int rowNum, int colNum)
			{
				Integer v=(Integer)value;
				if (v==RunStatus.LOCAL_CLUSTER)
				{
					return "Local";
				} else
				{
					return "<span class='fakelink'>"+v.toString()+"</span>";
				}
			}});
		ListGridField appField = new ListGridField("programName", "App Name", 80);
		appField.setType(ListGridFieldType.TEXT);

		ListGridField submitTimeField = new ListGridField("submittedTime", "Start Time", 100);
		submitTimeField.setType(ListGridFieldType.DATE);
		submitTimeField.setDateFormatter(DateDisplayFormat.TOUSSHORTDATETIME);
		submitTimeField.setEmptyCellValue("NA");

		ListGridField finishTimeField = new ListGridField("finishedTime", "End Time", 100);
		finishTimeField.setType(ListGridFieldType.DATE);
		finishTimeField.setDateFormatter(DateDisplayFormat.TOUSSHORTDATETIME);
		finishTimeField.setEmptyCellValue("NA");

		ListGridField exitCodeField = new ListGridField("exitvalue", "Exit Code", 40);
		exitCodeField.setType(ListGridFieldType.INTEGER);
		exitCodeField.setAlign(Alignment.CENTER);
		exitCodeField.setPrompt("Program Exit Value");
		exitCodeField.setCellFormatter(new CellFormatter(){

			public String format(Object value, ListGridRecord record, int rowNum, int colNum)
			{
				Integer v=(Integer)value;
				if (v!=0)
				{
					return "<span class='red'>"+v.toString()+"</span>";
				} else
				{
					return v.toString();
				}
			}});

		ListGridField runningField = new ListGridField("code", "Status(Kill)", 100);
		runningField.setType(ListGridFieldType.TEXT);
		runningField.setCellFormatter(new CellFormatter()
		{

			public String format(Object value, ListGridRecord record, int rowNum, int colNum)
			{
				if (value.toString().equals(RunStatusCode.PRESUBMIT.toString()))
				{
					return "PENDING";
				} else if (value.toString().equals(RunStatusCode.FAILEDSUBMISSION.toString()))
				{
					return "FAILED";
				} else if (value.toString().equals(RunStatusCode.RETRIEVING.toString()))
				{
					return "DOWNLOADING";
				}
				if (value.toString().equals(RunStatusCode.SUBMITTED.toString()) || value.toString().equals(RunStatusCode.RUNNING.toString()))
				{
					return "<span class='fakelink'>"+value.toString()+"(Kill)</span>";
				} else
					
					return value.toString();
			}
		});
		runningField.setAlign(Alignment.CENTER);
		
		ListGridField folderField = new ListGridField("files", "Files", 40);
		folderField.setType(ListGridFieldType.IMAGE);
		folderField.setImageURLSuffix(".gif");
		folderField.setCanSort(false);

		addCellClickHandler(new CellClickHandler()
		{
			public void onCellClick(CellClickEvent event)
			{

				final ListGridRecord record =  event.getRecord();
				int colNum = event.getColNum();
				if (colNum==2)
				{
					if (History.getToken().equals("user_jobs_"+record.getAttribute("id")))
						StaticHolder.jobPanel.ts.selectTab(1);
					else
						History.newItem("user_jobs_"+record.getAttribute("id"));
				} else if (colNum==3)
				{
					History.newItem("user_account_cluster");
				} else if (colNum==7)
				{
					ApplicationCallBack<String> callback = new ApplicationCallBack<String>()
					{

						public void onFailureAfter(Throwable caught)
						{
							StaticHolder.setStatusMessage(caught.getMessage(), 5);
						}

						public void onSuccessAfter(String result)
						{
							StaticHolder.setStatusMessage(result, 5);
							//JobGrid.this.reload();
						}

						public void execute()
						{
							UserAction.Util.getInstance().killJob(record.getAttribute("id"), this);
						}

					};
					callback.execute();
					
				}
				else if (colNum==8)
				{
					JobPanel jPanel=StaticHolder.jobPanel;
					//jPanel.getJobFiles().show();
					TreeNode jobRootNode=jPanel.getJobRootNode();
					jobRootNode.setAttribute("name", record.getAttribute("id"));
					jobRootNode.setAttribute("servername", record.getAttribute("workdir"));
					//hardcode since this node is not loaded from server
					jobRootNode.setAttribute("href", "/"+Constant.APPWEB_CONTEXT+"/apps/user/content/user/job/"+record.getAttribute("workdir"));
					Tree jobFiles=jPanel.getJobFiles().getTree();
					jobFiles.reloadChildren(jobRootNode);
					
				}
			}
		});

		setFields( appField, jobIdField,clusterField, submitTimeField, finishTimeField, exitCodeField, runningField, folderField);
	}

	boolean loaded = false;

	public void load()
	{
		if (loaded)
			return;
		StaticHolder.setStatusMessage("loading job history ...", 3);
		fetchData();
		loaded = true;
	}

	public void reload()
	{
		invalidateCache();
		loaded=false;
		load();
	}

}
